"""
在类上强制使用编程规约

问题：
    你的程序包含一个很大的类继承体系，你希望强制执行某些编程规约（或者代码诊断）来帮助程序员保持清醒。
解决办法：
     如果你想监控类的定义，通常可以通过定义一个元类。
     一个基本元类通常是继承自 type 并重定义它的 __new__() 方法 或者是 __init__() 方法。
"""

import logging
from inspect import signature


class MatchSignatureMeta(type):
    def __init__(self, clsname, bases, clsdict):
        super().__init__(clsname, bases, clsdict)

        sup = super(self, self)
        # 用来检测重载方法，确保它的调用参数跟父类中原始方法有着相同的参数签名。
        for name, value in clsdict.items():
            if name.startswith("_") or not callable(value):
                continue

            prev_dfn = getattr(sup, name, None)
            if prev_dfn:
                prev_sig = signature(prev_dfn)
                val_sig = signature(value)
                if prev_dfn != val_sig:
                    logging.warning("Signature mismatch in %s. %s != %s",
                                    value.__qualname__, prev_sig, val_sig)


class Root(metaclass=MatchSignatureMeta):
    pass


class User(Root):
    def say(self, name, content):
        pass

    def eat(self, food, *, love):
        pass


class Customer(User):
    def say(self, x, y):
        pass

    def eat(self, food, love):
        pass


def use_match():
    c = Customer()
    # 输出结果：
    """
    WARNING:root:Signature mismatch in Customer.say. (self, name, content) != (self, x, y)
    WARNING:root:Signature mismatch in Customer.eat. (self, food, *, love) != (self, food, love)
    """


if __name__ == '__main__':
    use_match()
